package com.kallsonys.jsf;

import com.kallsonys.object.Product;
import com.kallsonys.jsf.util.JsfUtil;
import com.kallsonys.jsf.util.PaginationHelper;
import com.kallsonys.object.Vrankingcategory;
import com.kallsonys.session.ProductFacade;

import com.kallsonys.session.SaveImage;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;

import javax.persistence.Query;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.SerializationUtils;
import org.apache.myfaces.custom.fileupload.UploadedFile;

@ManagedBean(name = "productController")
@SessionScoped
public class ProductController implements Serializable {

    private Product current;
    private DataModel items = null;
    private List<Vrankingcategory> rankingCategory;
    @EJB
    private com.kallsonys.session.ProductFacade ejbFacade;
    private PaginationHelper pagination;
    private int selectedItemIndex;
    private UploadedFile uploadedFile;
    private UploadedFile uploadedFileUpdate;
    private String fileName;
    /*Items de Query*/
    private String queryId;
    private String queryDescription;
    private String queryName;
    private String querySelector;
    private String queryStartDate;
    private String queryEndDate;
    private boolean rankingCategoryVisible;

    public UploadedFile getUploadedFileUpdate() {
        return uploadedFileUpdate;
    }

    public void setUploadedFileUpdate(UploadedFile uploadedFileUpdate) {
        this.uploadedFileUpdate = uploadedFileUpdate;
    }
    
    
    

    public boolean isRankingCategoryVisible() {
        return rankingCategory.size() > 0;
    }

    public void setRankingCategoryVisible(boolean rankingCategoryVisible) {
        this.rankingCategoryVisible = rankingCategoryVisible;
    }

    public List<Vrankingcategory> getRankingCategory() {

        //getRankingCategory().size();
        return rankingCategory;
    }

    public void setRankingCategory(List<Vrankingcategory> rankingCategory) {
        this.rankingCategory = rankingCategory;
    }

    public String getQueryEndDate() {
        return queryEndDate;
    }

    public void setQueryEndDate(String queryEndDate) {
        this.queryEndDate = queryEndDate;
    }

    public String getQueryStartDate() {
        return queryStartDate;
    }

    public void setQueryStartDate(String queryStartDate) {
        this.queryStartDate = queryStartDate;
    }

    public String getQueryDescription() {
        return queryDescription;
    }

    public void setQueryDescription(String queryDescription) {
        this.queryDescription = queryDescription;
    }

    public String getQueryId() {
        return queryId;
    }

    public void setQueryId(String queryId) {
        this.queryId = queryId;
    }

    public String getQueryName() {
        return queryName;
    }

    public void setQueryName(String queryName) {
        this.queryName = queryName;
    }

    public String sQueryId() {
        querySelector = "sQueryId";
        recreateModel();
        return "Query";
    }

    public String sQueryDescription() {
        querySelector = "sQueryDescription";
        recreateModel();
        return "Query";
    }

    public String sQueryName() {
        querySelector = "sQueryName";
        recreateModel();
        return "Query";
    }

    public String sQueryRankingProducts() {
        rankingCategory = new ArrayList<Vrankingcategory>();
        querySelector = "sQueryRankingProducts";
        recreateModel();
        return "RankingProduct";
    }

    public String sQueryRankingCategory() {
        items = null;
        pagination = null;
        querySelector = "";
        recreateModel();


        rankingCategory = getFacade().getByCategory(queryStartDate, queryEndDate);

        return "RankingProduct";
    }

    /*Metodos*/
    public ProductController() {
        rankingCategory = new ArrayList<Vrankingcategory>();
    }

    public String getImageProduct() {

        String retorno = "http://192.168.1.117/imagesweb/products/";
        retorno += current.getProductimageurl();
        retorno += "/large/";
        retorno += current.getProductid().longValue();
        retorno += ".jpg";
        System.out.println(retorno);
        return retorno;
    }

    public Product getSelected() {
        if (current == null) {
            current = new Product();
            selectedItemIndex = -1;
        }
        return current;
    }

    private ProductFacade getFacade() {
        return ejbFacade;
    }

    public PaginationHelper getPagination() {
        if (pagination == null) {
            pagination = new PaginationHelper(10) {

                @Override
                public int getItemsCount() {
                    return getFacade().count();
                }

                @Override
                public DataModel createPageDataModel() {
                    return new ListDataModel(getFacade().findRange(new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}));
                }
            };
        }
        return pagination;
    }

    public PaginationHelper getQueryXId() {
        if (pagination == null) {
            pagination = new PaginationHelper(10) {

                @Override
                public int getItemsCount() {
                    return getFacade().count();
                }

                @Override
                public DataModel createPageDataModel() {
                    if (querySelector != null) {
                        if (querySelector.equals("sQueryId")) {
                            return new ListDataModel(getFacade().getById(queryId));
                        }

                        if (querySelector.equals("sQueryDescription")) {
                            return new ListDataModel(getFacade().getByDescription(queryDescription));
                        }

                        if (querySelector.equals("sQueryName")) {
                            return new ListDataModel(getFacade().getByName(queryName));
                        }

                        if (querySelector.equals("sQueryRankingProducts")) {
                            return new ListDataModel(getFacade().getByRanking(queryStartDate, queryEndDate));
                        }
                    }

                    return new ListDataModel(new ArrayList<Product>());
                }
            };
        }
        return pagination;
    }

    public String prepareList() {
        items = null;
        pagination = null;
        selectedItemIndex = -1;
        recreateModel();
        return "List";
    }

    public String prepareView() {
        current = (Product) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "View";
    }

    public String prepareCreate() {
        current = new Product();
        selectedItemIndex = -1;
        return "Create";
    }

    public String prepareQuery() {
        current = new Product();
        items = null;
        pagination = null;
        selectedItemIndex = -1;
        return "Query";
    }

    public String prepareRankingProduct() {
        current = new Product();
        items = null;
        pagination = null;
        selectedItemIndex = -1;
        return "RankingProduct";
    }

    public UploadedFile getUploadedFile() {
        return uploadedFile;
    }

    public String getFileName() {
        return fileName;
    }

    // Setters ------------------------------------------------------------------------------------
    public void setUploadedFile(UploadedFile uploadedFile) {
        this.uploadedFile = uploadedFile;
    }

    public String create() {
        try {

            byte[] img = uploadedFile.getBytes();
            /*Adiciono la imagen*/
            //current.setProductimage(uploadedFile.getBytes());

            current.setProductdescription(current.getProductdescription().toUpperCase());
            current.setProductname(current.getProductname().toUpperCase());
            current.setProductenable(BigInteger.ONE);



            getFacade().create(current);

            String imgURL = SaveImage.SaveProductImg(current.getProductid().intValue(), img);
            System.out.println("Nombre de la Carpeta del Servicio de Imagene " + imgURL);
            current.setProductimageurl(imgURL);

            update();

            JsfUtil.addSuccessMessage("Producto Creado");
            return prepareCreate();
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, "Error Creando el Producto");
            return null;
        }
    }

    public String prepareEdit() {
        current = (Product) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "Edit";
    }

    public String update() {
        try {


            try {
                
                byte[] img = uploadedFileUpdate.getBytes();
                  
                  
                String imgURL = SaveImage.SaveProductImg(current.getProductid().intValue(), img);
                System.out.println("Nombre de la Carpeta del Servicio de Imagene " + imgURL);
                current.setProductimageurl(imgURL);

            } catch (Exception e) {
                e.printStackTrace();
            }

            current.setProductdescription(current.getProductdescription().toUpperCase());
            current.setProductname(current.getProductname().toUpperCase());
            current.setProductenable(BigInteger.ONE);

            getFacade().edit(current);
            JsfUtil.addSuccessMessage("Producto Modificado");
            return "View";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, "Error Modificando");
            return null;
        }
    }

    public String destroy() {
        current = (Product) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        performDestroy();
        recreateModel();
        return "List";
    }

    public String destroyAndView() {
        performDestroy();
        recreateModel();
        updateCurrentItem();
        if (selectedItemIndex >= 0) {
            return "View";
        } else {
            // all items were removed - go back to list
            recreateModel();
            return "List";
        }
    }

    private void performDestroy() {
        try {
            getFacade().remove(current);
            JsfUtil.addSuccessMessage("Producto Borrado");
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, "Error Borrando");
        }
    }

    private void updateCurrentItem() {
        int count = getFacade().count();
        if (selectedItemIndex >= count) {
            // selected index cannot be bigger than number of items:
            selectedItemIndex = count - 1;
            // go to previous page if last page disappeared:
            if (pagination.getPageFirstItem() >= count) {
                pagination.previousPage();
            }
        }
        if (selectedItemIndex >= 0) {
            current = getFacade().findRange(new int[]{selectedItemIndex, selectedItemIndex + 1}).get(0);
        }
    }

    public DataModel getItems() {
        if (items == null) {
            items = getPagination().createPageDataModel();
        }
        return items;
    }

    public DataModel getItemsXId() {
        if (items == null) {
            items = getQueryXId().createPageDataModel();
        }
        return items;
    }

    private void recreateModel() {
        items = null;
    }

    public String next() {
        getPagination().nextPage();
        recreateModel();
        return "List";
    }

    public String previous() {
        getPagination().previousPage();
        recreateModel();
        return "List";
    }

    public SelectItem[] getItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), false);
    }

    public SelectItem[] getItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), true);
    }

    @FacesConverter(forClass = Product.class)
    public static class ProductControllerConverter implements Converter {

        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            ProductController controller = (ProductController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "productController");
            return controller.ejbFacade.find(getKey(value));
        }

        java.math.BigDecimal getKey(String value) {
            java.math.BigDecimal key;
            key = new java.math.BigDecimal(value);
            return key;
        }

        String getStringKey(java.math.BigDecimal value) {
            StringBuffer sb = new StringBuffer();
            sb.append(value);
            return sb.toString();
        }

        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof Product) {
                Product o = (Product) object;
                return getStringKey(o.getProductid());
            } else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + ProductController.class.getName());
            }
        }
    }
}
